package com.springcloud.gateway.service;

import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

@Service
@Slf4j
public class SentinelRuleService implements InitializingBean {

    //接口流控
    public void updFlowRules() {
        Set<GatewayFlowRule> gatewayFlowRules = new HashSet<>();
        gatewayFlowRules.add(new GatewayFlowRule("provider")
                .setCount(1)
                .setIntervalSec(1)
        );
        GatewayFlowRule gatewayFlowRule = new GatewayFlowRule();
        gatewayFlowRule.setResource("provider_service");
        gatewayFlowRule.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME);
        gatewayFlowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        gatewayFlowRule.setIntervalSec(1);
        gatewayFlowRule.setCount(3);
        gatewayFlowRules.add(gatewayFlowRule);

        GatewayRuleManager.loadRules(gatewayFlowRules);
        log.info("限流规则已生效：{}",gatewayFlowRules.size());
    }

    //接口降级
    public void updFuseRules() {
        ArrayList<DegradeRule> degradeRules = new ArrayList<>();
        DegradeRule degradeRule = new DegradeRule();
        degradeRule.setResource("provider");
        degradeRule.setMinRequestAmount(5);
        degradeRule.setStatIntervalMs(10);
        degradeRule.setTimeWindow(10);
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        degradeRule.setCount(100);
        degradeRule.setSlowRatioThreshold(new BigDecimal(30).divide(new BigDecimal(100),2, RoundingMode.HALF_UP).doubleValue());

        degradeRules.add(degradeRule);
        DegradeRuleManager.loadRules(degradeRules);
        log.info("熔断规则已生效：{}",degradeRules.size());
    }

    //api组定义
    public void updApi() {
        Set<ApiDefinition> apiDefinitions = new HashSet<>();
        ApiDefinition apiDefinition = new ApiDefinition("provider_service");

        Set<ApiPredicateItem> apiPredicateItems = new HashSet<>();
        ApiPathPredicateItem item = new ApiPathPredicateItem();
        item.setPattern("/provider/**");
        item.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX);
        apiPredicateItems.add(item);

        apiDefinition.setPredicateItems(apiPredicateItems);
        apiDefinitions.add(apiDefinition);
        GatewayApiDefinitionManager.loadApiDefinitions(apiDefinitions);
        log.info("自定义api组已更新,size:{}", apiDefinitions.size());
    }

    @Override
    public void afterPropertiesSet() {
        updFlowRules();
        updFuseRules();
        updApi();
    }
}
